if not menu then menu = {} end

if not menu.action then

dofile (getScriptPath() .. "\\..\\lib\\lib.lua")
dofile (getScriptPath() .. "\\..\\lib\\actions.lua")

dofile (getScriptPath() .. "\\orders.lua")

menu.action = {
	act = {"bl", "sl", "quit", "exit", "break", "half", "even", "fix", "shift"},
}


processor:AddInit(function()
	window:AddRow()
	menu.action.row = window:AddRow()
	menu.action.rows = 6
	for i = 2, menu.action.rows do
		window:AddRow()
	end
end)


processor:AddInit(function()		-- buy limit
	local index = 1
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row
	menu.action.act[ menu.action.act[index] ].col = 1
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		if menu.action.act[ menu.action.act[index] ].volume then
			menu.action:Limit()
		end
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
end)


processor:AddInit(function()		-- sell limit
	local index = 2
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row
	menu.action.act[ menu.action.act[index] ].col = 2
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		if menu.action.act[ menu.action.act[index] ].volume then
			menu.action:Limit()
		end
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
end)


processor:AddInit(function()		-- quit
	local index = 3
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 2
	menu.action.act[ menu.action.act[index] ].col = 1
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		actions:Quit()
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(255, 0, 0)
	)
end)


processor:AddInit(function()		-- exit
	local index = 4
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 2
	menu.action.act[ menu.action.act[index] ].col = 2
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		local volume, instrument = menu.risk:Get()
		if instrument then actions:Exit(instrument) end
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(255, 128, 128)
	)
end)


processor:AddInit(function()		-- break
	local index = 5
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 2
	menu.action.act[ menu.action.act[index] ].col = 3
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		local volume, instrument = menu.risk:Get()
		if instrument then actions:Break(instrument) end
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(255, 255, 0)
	)
end)


processor:AddInit(function()		-- half
	local index = 6
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 4
	menu.action.act[ menu.action.act[index] ].col = 1
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		local volume, instrument = menu.risk:Get()
		if instrument then actions:Half(instrument) end
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(255, 255, 0)
	)
end)


processor:AddInit(function()		-- even
	local index = 7
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 4
	menu.action.act[ menu.action.act[index] ].col = 2
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		menu.action:SetEven()
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(0, 255, 0)
	)
end)


processor:AddInit(function()		-- fix
	local index = 8
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 5
	menu.action.act[ menu.action.act[index] ].col = 1
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		menu.action:FixStops()
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(0, 255, 255)
	)
end)


processor:AddInit(function()		-- shift
	local index = 9
	menu.action.act[ menu.action.act[index] ] = {index = index}
	menu.action.act[ menu.action.act[index] ].row = menu.action.row + 5
	menu.action.act[ menu.action.act[index] ].col = 2
	
	menu.action.act[ menu.action.act[index] ].exec = function(index)
		menu.action:ShiftLimits()
	end
	
	window:SetCell(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		string.upper(menu.action.act[index])
	)
	window:SetColor(menu.action.act[ menu.action.act[index] ].row,
		menu.action.act[ menu.action.act[index] ].col,
		RGB(255, 255, 0)
	)
end)


processor:AddHandler("OnTableNotification", function(data)
	if data.msg == QTABLE_LBUTTONUP then
		if data.par1 >= menu.action.row
			and data.par1 < menu.action.row + menu.action.rows
		then
			for i = 1, #menu.action.act do
				if menu.action.act[ menu.action.act[i] ].row == data.par1
					and menu.action.act[ menu.action.act[i] ].col == data.par2
				then
					menu.action.act[ menu.action.act[i] ].exec(i)
				end
			end
		elseif data.par1 == menu.label.show.sl.row
			and data.par2 == 2
		then
			menu.action:SetStop()
		elseif data.par1 == menu.label.show.sl.row
			and data.par2 == 3
		then
			menu.action:SetEven()
		elseif data.par1 == menu.label.show.tp.row
			and data.par2 >= 2
		then
			menu.action:SetTake()
		end
	end
end)


processor:AddTimer(function()
	menu.action:ShowBlockLimit()
end)
	
	
processor:AddTimer(function()
	local data = actions:LoadAction()
	if type(data) == "table" then
		if data.action == "even" then
			menu.action:SetEven(data)
		elseif data.action == "enter" then
			menu.action:Limit()
		end
	end
end)


processor:AddTimer(function()
	if menu.action.kill_limit then
		if not menu.action.kill_limit.delay and orders:GetPosition(menu.action.kill_limit.code, false) == 0 and not orders:InProcess() then
			menu.action.kill_limit.delay = lib:tickseconds() + 5
		end
		if menu.action.kill_limit.delay and (menu.portfolio.changed or menu.action.kill_limit.delay < lib:tickseconds()) then
			menu.action.kill_limit = nil
			menu.action:Limit()
		elseif lib:tickseconds() - menu.action.kill_limit.time > lib.global.file_ttl then
			menu.action.kill_limit = nil
		end
	end
end)


processor:AddTimer(function()
	if menu.risk.changed
		--and menu.action.long ~= menu.label.long
	then
		if menu.action.long then
			menu.action.act.bl.volume = nil
			menu.action.act.bl.instrument = nil
			window:SetColor(menu.action.act.bl.row,
				menu.action.act.bl.col,
				QTABLE_DEFAULT_COLOR
			)
		else
			menu.action.act.sl.volume = nil
			menu.action.act.sl.instrument = nil
			window:SetColor(menu.action.act.sl.row,
				menu.action.act.sl.col,
				QTABLE_DEFAULT_COLOR
			)
		end
		window:SetCell(menu.action.act.bl.row, 3, "")
		window:SetCell(menu.action.act.sl.row, 3, "")
		menu.action.long = menu.label.long
	end
end)


processor:AddTimer(function()
	if menu.risk.changed then
		if menu.action.long then
			menu.action.act.bl.volume, menu.action.act.bl.instrument =
				menu.risk:Get()
			if menu.action.act.bl.volume > 0 then
				window:SetCell(menu.action.act.bl.row,
					3, tostring(menu.action.act.bl.volume))
				window:SetColor(menu.action.act.bl.row,
					menu.action.act.bl.col,
					RGB(128, 255, 128)
				)
			end
		else
			menu.action.act.sl.volume, menu.action.act.sl.instrument =
				menu.risk:Get()
			if menu.action.act.sl.volume > 0 then
				window:SetCell(menu.action.act.sl.row,
					3, tostring(menu.action.act.sl.volume))
				window:SetColor(menu.action.act.sl.row,
					menu.action.act.sl.col,
					RGB(255, 128, 128)
				)
			end
		end
	end
end)


function menu.action:ShowBlockLimit()
	if orders:InProcess()
		and not self.block_limit
	then
		self.block_limit = true
		window:SetColor(self.act.bl.row,
			3,
			RGB(255, 255, 0)
		)
	elseif self.block_limit
		and not orders:InProcess()
	then
		self.block_limit = nil
		window:SetColor(self.act.bl.row,
			3,
			QTABLE_DEFAULT_COLOR
		)
	end
end


function menu.action:FixStops()
	local now = orders:InProcess()
	if not now and menu.chart.instrument then
		local instrument = lib:clone(menu.chart.instrument)
		local instrument_pos = lib:GetInstrumentPosition(instrument.code)
		local stop_pos, limit_pos = orders:GetPosition(instrument.code)
		
		if instrument_pos ~= 0 and limit_pos == 0 then		-- no activated stops
			if stop_pos ~= 0 then
				message("FixStops - faced positions " .. tostring(instrument_pos) .. " " .. tostring(stop_pos))
					
				if sign(instrument_pos) ~= sign(stop_pos) then
					stop_pos = 0		-- create stops from scratch
					
					for _, order in pairs(orders:GetActiveStops(instrument.code)) do
						orders:KillStopOrder(order)
					end
				else
					local groups = orders:GetActiveStopGroups(instrument.code, true)
					local count, tail
					
					processor:log(message("FixStops - #groups " .. tostring(#groups)))
					
					if #groups > 1 then
						count = int(math.abs(instrument_pos) / #groups)			
					elseif #groups == 1 and #groups[1] > 1 then
						count = int(math.abs(instrument_pos) / 2)			
					--else
						--count = int(math.abs(instrument_pos))
					end
					
					if count then
						processor:log("FixStops - fix " .. tostring(math.abs(instrument_pos) - math.abs(stop_pos)))
						
						tail = int(math.abs(instrument_pos) - count)
						
						for j, group in ipairs(groups) do
							for i, stop in ipairs(groups[j]) do
								if i == 1 then
									if j == 1 then
										orders:SetStopLots(stop, tail)
									else
										orders:SetStopLots(stop, count)
									end
								elseif i == 2 and #groups == 1 then
									orders:SetStopLots(stop, count)
								else
									orders:KillStopOrder(stop)
								end
							end
						end
					else		-- one stop order - add the second one
						count = int(math.abs(instrument_pos) / 2)
						tail = int(math.abs(instrument_pos) - count)
							
						instrument.ex__ = {
							sl = orders:GetStopPrice(groups[1][1]),
							tp = orders:GetTakePrice(groups[1][1]),
							qty = tail,
						}
						
						if count > 0 and tail > 0 and instrument.ex__.tp then
							orders:SetStopLots(groups[1][1], count)
							
							orders:SendTakeStop(instrument)
						else
							orders:SetStopLots(groups[1][1], int(math.abs(instrument_pos)))
						end
					end
				end
			end
			
			if stop_pos == 0 and menu.label.price.lm and menu.label.price.sl then
				if sign(instrument_pos) ~= sign(menu.label.price.lm - menu.label.price.sl) then
					fail("FixStops - faced labels")
				else
					instrument.ex__ = {
						sl = menu.label.price.sl,
						lm = menu.label.price.lm,
						tp = menu.label.price.tp,
					}
					
					--if math.abs(instrument_pos) >= 2 then
						instrument.qty__ = int(math.abs(instrument_pos) / 2)
					--else
					--	instrument.qty__ = 0
					--end
					
					if instrument.qty__ > 0 then
						if instrument.ex__.tp then
							orders:SendTakeStop(instrument)
						else
							orders:SendStop(instrument)
						end
					end
					
					instrument.qty__ = int(math.abs(instrument_pos) - instrument.qty__)
					
					if instrument.qty__ > 0 then
						if instrument.ex__.tp then
							orders:SendTakeStop(instrument)
						else
							orders:SendStop(instrument)
						end
					end
				end
			end
			
			self:ShowBlockLimit()
		end
	else
		message("FixStops blocked - a transaction in progress")
		lib:SaveFile(lib.path.log .. "limit_block.txt", lib:tostring(now))
	end
end


function menu.action:ShiftLimits()
	local now = orders:InProcess()
	if not now and menu.chart.instrument then
		message("Shift " .. menu.chart.instrument.code)
		actions:Shift(menu.chart.instrument)
	else
		message("ShiftLimits blocked - a transaction in progress")
		lib:SaveFile(lib.path.log .. "limit_block.txt", lib:tostring(now))
	end
end


function menu.action:Limit()
	local now = orders:InProcess()
	if not now then
		local volume, instrument, max_volume = menu.risk:Get()
		now = lib:tickseconds()
                local pos, limits = orders:GetPosition(instrument.code)
		
		if instrument and volume >= 2
			and pos == 0				-- papers
		then
			if limits ~= 0 then		-- limits
			
				self.kill_limit = {time = now, code = instrument.code}
				actions:Break(instrument.code)
				self:ShowBlockLimit()
				
			else
			
				if menu.label.price.lm > menu.label.price.sl then
					instrument.side__ = "B"
				elseif menu.label.price.lm < menu.label.price.sl then
					instrument.side__ = "S"
				else
					return
				end
				
				instrument.sl__ = menu.label.price.sl
				instrument.lm__ = menu.label.price.lm
				instrument.tp__ = menu.label.price.tp
				instrument.qty__ = int(volume / 2)
				
				local risk, max_lots = lib:CalcRisk(instrument, instrument.lm__, instrument.sl__, instrument.qty__)
				
				instrument.risk__ = instrument.qty__ > 1 and risk
				instrument.credit__ = instrument.qty__ > 1 and instrument.qty__ / max_lots
					
				if orders:SendLimit(instrument) then
					self:ShowBlockLimit()
					
					if menu.label.price.tev and menu.label.price.tp
						and (menu.label.price.lm > menu.label.price.sl
							and menu.label.price.tev > menu.label.price.lm
							and menu.label.price.tev < menu.label.price.tp
							--and menu.label.price.tev  * 2 - menu.label.price.lm < menu.label.price.tp
						or menu.label.price.lm < menu.label.price.sl
							and menu.label.price.tev < menu.label.price.lm
							and menu.label.price.tev > menu.label.price.tp
							--and menu.label.price.tev  * 2 - menu.label.price.lm > menu.label.price.tp
						)
					then
						instrument.tp__ = menu.label.price.tev
					end
					
					orders:SendLimit(instrument)
				end
			end
		end
	else
		message("Limit blocked - a transaction in progress")
		lib:SaveFile(lib.path.log .. "limit_block.txt", lib:tostring(now))
	end
end


function menu.action:SetStop()
	if menu.chart.instrument and not orders:SetStopPrice(menu.chart.instrument.code, menu.label.price.sl) then
		message("SetStop failed " .. menu.chart.instrument.code .. " " .. tostring(menu.label.price.sl))
	end
	self:ShowBlockLimit()
end


function menu.action:SetEven(instrument)
	instrument = instrument or menu.chart.instrument
	
	if instrument and menu.label.price.lm and menu.label.price.sl then
		orders:SetEven(instrument.code or instrument.sec_code, menu.label.price.lm > menu.label.price.sl, menu.portfolio.commission)
		--orders:SetEven(instrument.code or instrument.sec_code, nil, menu.portfolio.commission)
	end
	
	self:ShowBlockLimit()
end


function menu.action:SetTake()
	if menu.chart.instrument and not orders:SetTakePrice(menu.chart.instrument.code, menu.label.price.tp) then
		message("SetTake failed " .. menu.chart.instrument.code .. " " .. tostring(menu.label.price.tp))
	end
	self:ShowBlockLimit()
end


end	-- of file
